Linux - return codes

Overview of the most popular return codes in Unix-like systems. The exit and return commands and what their arguments mean.

release date: 2025-09-05

modification date: 2025-09-10

introduction

Most Linux users have surely come across the concept of return code - for example, while reading forums, working in the terminal, executing everyday commands, or encountering errors. This issue may be especially familiar to Termux users, who see a message about this code every time they exit the terminal with a code other than 0 - as shown in the picture below. Other places where it appears include logs of many packages or systemd logs.
Termux - return code
Return codes inform the user as well as other processes, programs, or scripts whether a task was successful or not, and why. Different codes indicate different events and reasons for errors. The most common ones are 0 and 1 - no error or an error occurred. But that’s just a taste and a pinch of everything this topic has to offer.

types of return codes

Every program, script, or process can theoretically return any value as its return code. In practice, however, the return code value is an 8-bit value (0..255) - which means there are 0-255 actual return codes, of which only a smaller portion have any practical use and convey meaningful information.

Below is a table containing the most common return codes (in Bash) along with a brief note. We will look at the details of some of them later in the article.
Code Description
0Success
1Operation not permitted / General return
2No such file or directory
3No such process
4Interrupted system call
5Input/output error
6No such device or address
7Argument list too long
8Exec format error
9Bad file descriptor
10No child processes
11Resource temporarily unavailable
12Cannot allocate memory
13Permission denied
14Bad address
15Block device required
16Device or resource busy
17File exists
18Invalid cross-device link
19No such device
20Not a directory
21Is a directory
22Invalid argument
23Too many open files in system
24Too many open files
25Inappropriate ioctl for device
26Text file busy
27File too large
28No space left on device
29Illegal seek
30Read-only file system
31Too many links
32Broken pipe
33Numerical argument out of domain
34Numerical result out of range
35Resource deadlock avoided
36File name too long
37No locks available
38Function not implemented
39Directory not empty
40Too many levels of symbolic links
42No message of desired type
43Identifier removed
44Channel number out of range
45Level 2 not synchronized
46Level 3 halted
47Level 3 reset
48Link number out of range
49Protocol driver not attached
50No CSI structure available
51Level 2 halted
52Invalid exchange
53Invalid request descriptor
54Exchange full
55No anode
56Invalid request code
57Invalid slot
59Bad font file format
60Device not a stream
61No data available
62Timer expired
63Out of streams resources
64Machine is not on the network
65Package not installed
66Object is remote
67Link has been severed
68Advertise error
69Srmount error
70Communication error on send
71Protocol error
72Multihop attempted
73RFS specific error
74Bad message
75Value too large for defined data type
76Name not unique on network
77File descriptor in bad state
78Remote address changed
79Can not access a needed shared library
80Accessing a corrupted shared library
81.lib section in a.out corrupted
82Attempting to link in too many shared libraries
83Cannot exec a shared library directly
84Invalid or incomplete multibyte or wide character
85Interrupted system call should be restarted
86Streams pipe error
87Too many users
88Socket operation on non-socket
89Destination address required
90Message too long
91Protocol wrong type for socket
92Protocol not available
93Protocol not supported
94Socket type not supported
95Operation not supported
96Protocol family not supported
97Address family not supported by protocol
98Address already in use
99Cannot assign requested address
100Network is down
101Network is unreachable
102Network dropped connection on reset
103Software caused connection abort
104Connection reset by peer
105No buffer space available
106Transport endpoint is already connected
107Transport endpoint is not connected
108Cannot send after transport endpoint shutdown
109Too many references
110Connection timed out
111Connection refused
112Host is down
113No route to host
114Operation already in progress
115Operation now in progress
116Stale file handle
117Structure needs cleaning
118Not a XENIX named type file
119No XENIX semaphores available
120Is a named type file
121Remote I/O error
122Disk quota exceeded
123No medium found
125Operation canceled
126Command invoked cannot execute / Required key not available
127Command not found / Key has expired
128Invalid exit argument / Key has been revoked
129Signal 1 return / Key was rejected by service
130Signal 2 return / Owner died
131Signal 3 return / State not recoverable
132Signal 4 return / Operation not possible due to RF-kill
133Signal 5 return / Memory page has hardware error
134-192Signal 6-64 return / Unspecified
193–254Reserved / Unspecified
255Exit status out of range / Critical script or program error
The author of the software/script may impose their own meaning on specific codes. The table presents examples for Bash as both an interpreter and a shell.
The most commonly encountered/used return codes include, among others:
  • Code 0 – the code returned after a process finishes successfully. It indicates that everything went smoothly.
  • Code 1 – a universal "general" code indicating unspecified/other errors. Often used in scripts or programs where it’s hard to assign a specific code to an event.
  • Code 126 – the code returned by the shell/interpreter when attempting to execute an invalid/incompatible executable or an executable without proper x permissions.
  • Code 127 – returned by the shell when trying to run a non-existent script or program, or a command not found in $PATH.
  • Code 130 – returned when a script/program is terminated by a SIGINT signal (CTRL + C). It indicates the process was manually interrupted/canceled.
  • Code 255 – similar to code 1, but often used for critical errors. Used in scripts/programs for critical unspecified errors.

`exit` and `return`

Both return and exit are commands used in programming and scripting to provide a return code, signaling the outcome of a process, function, or script. They serve to communicate success, failure, or specific error states to the calling environment or other programs. While they are related in purpose, they are used in different contexts and have distinct behaviors.

Exit: The exit command is used to terminate an entire script or program immediately and return a specific return code to the operating system or calling process. Once executed, no further commands in the script are run (except trap command), and the return code becomes the script’s final status. It is commonly used in shell scripts, batch files, and programs to signal that a process has finished, whether successfully or due to an error.

Return: The return command, on the other hand, is primarily used within functions or subroutines to exit that function and provide a return code to the calling function or script. Unlike exit, it does not terminate the entire script but only the current function, allowing the rest of the script to continue executing. It’s essential for modular programming and for functions to communicate their results back to the main script logic.

It’s important to note that the behavior of exit and return also depends on the context in which the script is running. The exit command terminates scripts executed directly from a shell, ending the script and returning the code to the shell. However, when used in shell initialization or configuration scripts, exit will close the shell itself along with the terminal, which is usually undesirable. In such cases, return is preferred, as it ends the execution of the initialization or configuration script without closing the shell, allowing the terminal session to continue running normally.
You cannot use exit in scripts/functions sourced in shell initialization files (e.g., .bashrc, .zshrc, etc.). Using exit in this context will immediately close the shell along with the terminal.

returns in scripts

Values from return codes can be used, for example, in Bash scripts for communication between functions, for use in loops, and so on. Below are a few examples of using return codes as well as the return command itself.
until false; do
	# do something
	if ! something; then
		return 1
	fi
done
As the first example, let’s take the until loop (the opposite of a while loop), which runs (in this case) until a non-zero value is returned by return. This loop treats 0 as true and 1..255 as false.
if some-command; then
	echo "Returned: success"
else
	echo "Returned: error"
fi
Similarly, the return code status can be used in conditional if statements. An if condition evaluates true for a returned code of 0 and false for any other value.
In the example, however, it is shown literally that if itself can only distinguish between 0 and non-0.
Here, I will also introduce a new symbol into the article: $?.
Echo return code
The variable $? stores the return code of the previously executed command/process. It behaves just like any other variable - it can be used in code, in conditions, and displayed, for example, with echo.
In the screenshot above, you can see how the return code 5 is set (also indicated by the graphical element of the prompt), which is then displayed using echo $?.
if some-command; then
	echo "Returned: 0"
else
	echo "Returned: $?"
fi
The example above is once again a simple demonstration of obtaining information from the return code in a basic if condition, but this time using the $? variable, which tells us exactly which code was returned.
You can freely use another condition inside the current one to check [ $? -eq X ] or something similar (to prepare different actions depending on the returned code), or…
some-command

case $? in
	0) echo "Success" ;;
	1) echo "Some error occured" ;;
	126) echo "Command not found" ;;
	255) echo "Some error occured" ;;
esac
The next example is a bit more meaningful - after executing a command, we use a case switch to perform specific tasks more precisely depending on the returned return code.
In this particular use case, return codes don’t necessarily have to indicate errors at all, but rather represent general values. Want me to provide an example?
count_lines() {
	return $( wc -l < some_file.txt )
}

count_lines

echo "Lines count: $?"
In this slightly abstract example, the return command passes, in a way, the number of lines of some file as the exit status of the function, which can then be read afterward. Perhaps someone might find a concrete use for this approach instead of creating global or local variables - this value is only preserved until the next command is executed.
func1() {
	# do something
	if ! something; then
		return 1
	fi
}
func2() {
	# do something
	if ! something; then
		return 1
	fi
}
func3() {
	# do something
	if ! something; then
		return 1
	fi
}

STATUS=0
for F in {1..3}; do
	func${F}
	STATUS=$(( STATUS + $? ))
done

echo "$STATUS of 3 functions failed."
Another (and the last one for now), somewhat imaginary and rather uncommon example is counting the number of errors from functions executed in bulk, one after another.

outro

Return codes may seem like a small detail, but they play a key role in how Linux and shell environments communicate success, failure, and specific states.
By understanding how exit, return, and the $? variable work, you can write more reliable scripts, handle errors more gracefully, and even design your own logic using exit codes.
In short: mastering return codes means mastering control over your scripts and processes.
If you believe that my work has meaning and value, consider making a donation so I can continue to grow, full of inspiration - >link<